#include "myio.hpp"
int MyIO::readline(SOCKET fd, void *vptr, DWORD maxlen)
{
	DWORD n;
	SSIZE_T rc;
	char c, *ptr;
	ptr = (char *)vptr;
	for (n = 1; n < maxlen; ++n)
	{
		if ((rc = my_read(fd, &c)) == 1)
		{
			*ptr++ = c;
			if (c == '\n')
				break;
		}
		else if (rc == 0)
		{
			*ptr = 0;
			return n - 1;
		}
		else
			return -1;
	}
	*ptr = 0;
	return n;
}

int MyIO::writen(SOCKET fd, const void* vptr, DWORD n)
{
	DWORD nleft, nwritten, flags = 0;
	int res;
	const char *ptr;
	ptr = (const char*)vptr;
	nleft = n;
	CopyMemory(_writebuf, ptr, n);
	WSABUF buf;
	buf.buf = _writebuf;
	buf.len = n;
	while (nleft > 0)
	{
		res = WSASend(fd, &buf, 1, &nwritten, flags, NULL, NULL);
		if (res < 0)
			return 0;
		nleft -= nwritten;
		ptr += nwritten;
	}
	return n;
}

SSIZE_T MyIO::my_read(SOCKET fd, char *ptr)
{
	DWORD flags = 0;
	WSABUF buf;
	buf.buf = _readbuf;
	buf.len = sizeof(_readbuf);
	if (read_cnt == 0)
	{
	again:
		int res = WSARecv(fd, &buf, 1, &read_cnt, &flags, NULL, NULL);
		if (res == SOCKET_ERROR&&WSAGetLastError() == WSAEINTR)
			goto again;
		else if (res == SOCKET_ERROR)
			return -1;
		read_ptr = _readbuf;
	}
	read_cnt--;
	*ptr = *read_ptr++;
	return 1;
}
